home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
c
/
indents.zip
/
lexi.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-05-30
|
22KB
|
597 lines
/**
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980 The Regents of the University of California.
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted provided
* that the above copyright notice and this paragraph are duplicated in all
* such forms and that any documentation, advertising materials, and other
* materials related to such distribution and use acknowledge that the
* software was developed by the University of California, Berkeley, the
* University of Illinois, Urbana, and Sun Microsystems, Inc. The name of
* either University or Sun Microsystems may not be used to endorse or
* promote products derived from this software without specific prior written
* permission. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
* OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#include "globals.h"
#include "codes.h"
#ifndef lint
# ifndef ANSIC
static char sccsid[] = "@(#)lexi.c 6.0 (Berkeley) 92/06/15";
# endif /* ANSIC */
#endif /* not lint */
/* Here we have the token scanner for indent. It scans off one token and
* puts it in the global variable "token". It returns a code, indicating the
* type of token scanned. */
#include <ctype.h>
#include <string.h>
typedef enum char_type {
alphanum = 1,
opchar = 3,
colonchar = 4
} char_type;
struct templ {
char *rwd;
int rwcode;
cplus_flag cplus;
};
struct templ specials[100] =
{
{"switch", 1, c_and_cplus},
{"case", 2, c_and_cplus},
{"break", 0, c_and_cplus},
{"struct", 3, c_and_cplus},
{"union", 3, c_and_cplus},
{"enum", 3, c_and_cplus},
{"default", 2, c_and_cplus},
{"int", 4, c_and_cplus},
{"char", 4, c_and_cplus},
{"float", 4, c_and_cplus},
{"double", 4, c_and_cplus},
{"long", 4, c_and_cplus},
{"short", 4, c_and_cplus},
{"typedef", 8, c_and_cplus},
{"unsigned", 4, c_and_cplus},
{"register", 4, c_and_cplus},
{"static", 4, c_and_cplus},
{"global", 4, c_and_cplus},
{"extern", 4, c_and_cplus},
{"void", 4, c_and_cplus},
{"goto", 0, c_and_cplus},
{"return", 0, c_and_cplus},
{"if", 5, c_and_cplus},
{"while", 5, c_and_cplus},
{"for", 5, c_and_cplus},
{"else", 6, c_and_cplus},
{"do", 6, c_and_cplus},
{"sizeof", 7, c_and_cplus},
{"class", 3, cplus_only},
{"public", 2, cplus_only},
{"private", 2, cplus_only},
{"protected", 2, cplus_only},
{"volatile", 4, c_and_cplus},
{0, 0}
};
char chartype[128] =
{ /* this is used to facilitate the decision of
* what type (alphanumeric, operator) each
* character is */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 3, 0, 0, 1, 3, 3, 0,
0, 0, 3, 3, 0, 3, 0, 3,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 4, 0, 3, 3, 3, 3,
0, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 0, 0, 3, 1,
0, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 3, 0, 3, 0
};
#ifdef ANSIC
int lexi(void)
#else /* ANSIC */
int lexi()
#endif /* ANSIC */
{
register char *tok = NULL; /* local pointer to next char in token */
int unary_delim;/* this is set to 1 if the current token
*
* forces a following operator to be unary */
static int last_code = 0; /* the last token type returned */
static int l_struct = 0; /* set to 1 if the last token was
* 'struct' */
static int l_struct_start = 0; /* set at struct, cleared at { or ; */
static int l_class = 0;/* in c++, class name coming next. */
int code; /* internal code to be returned */
char qchar; /* the delimiter character for a string */
tok = token; /* point to start of place to save token */
unary_delim = false;
ps.col_1 = ps.last_nl; /* tell world that this token started in
* column 1 iff the last thing scanned was a
* newline */
ps.last_nl = false;
while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */
ps.col_1 = false; /* leading blanks imply token is not in
* column 1 */
if (++buf_ptr >= buf_end)
fill_buffer();
}
/* Scan an alphanumeric token */
/* In c++, :: starting token is OK, as is ~ sometimes */
/* well, int x = ~y; will work oddly here */
if (((char_type) chartype[*buf_ptr] == alphanum || buf_ptr[0] == '.' && isdigit(buf_ptr[1])) ||
(cplus && buf_ptr[0] == ':' && buf_ptr[1] == ':') ||
(cplus && ps.in_decl && *buf_ptr == '~'
&& (char_type) chartype[buf_ptr[1]] == alphanum) /* destructors in
* classdefs */
) {
/* we have a character or number */
register char *j = NULL; /* used for searching through list of
* reserved words */
register struct templ *p;
if (isdigit(*buf_ptr) || buf_ptr[0] == '.' && isdigit(buf_ptr[1])) {
int seendot = 0,
seenexp = 0;
if (*buf_ptr == '0' &&
(buf_ptr[1] == 'x' || buf_ptr[1] == 'X')) {
*tok++ = *buf_ptr++;
*tok++ = *buf_ptr++;
while (isxdigit(*buf_ptr))
*tok++ = *buf_ptr++;
} else
while (1) {
if (*buf_ptr == '.')
if (seendot)
break;
else
seendot++;
*tok++ = *buf_ptr++;
if (!isdigit(*buf_ptr) && *buf_ptr != '.')
if ((*buf_ptr != 'E' && *buf_ptr != 'e') || seenexp)
break;
else {
seenexp++;
seendot++;
*tok++ = *buf_ptr++;
if (*buf_ptr == '+' || *buf_ptr == '-')
*tok++ = *buf_ptr++;
}
}
if (*buf_ptr == 'L' || *buf_ptr == 'l')
*tok++ = *buf_ptr++;
} else {
int first;
first = 1;
while ((char_type) chartype[*buf_ptr] == alphanum ||
(buf_ptr[0] == ':' && buf_ptr[1] == ':' && cplus) ||
(cplus && first && buf_ptr[0] == '~')) { /* copy it over */
int colonp;
first = 0;
colonp = *buf_ptr == ':';
*tok++ = *buf_ptr++;
if (colonp) {
*tok++ = *buf_ptr++;
/* foo::~foo */
if (*buf_ptr == '~')
*tok++ = *buf_ptr++;
colonp = 0;
}
if (buf_ptr >= buf_end)
fill_buffer();
}
}
*tok++ = '\0';
while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */
if (++buf_ptr >= buf_end)
fill_buffer();
}
ps.its_a_keyword = false;
ps.sizeof_keyword = false;
if (l_struct) { /* if last token was 'struct', then this